package com.zeen.wima.common;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;
import org.json.JSONArray;
import org.json.JSONObject;

import android.app.Application;
import android.content.Context;
import android.location.Criteria;
import android.location.GpsStatus;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.SystemClock;
import android.telephony.TelephonyManager;
import android.telephony.gsm.GsmCellLocation;

public class LocationMonitor {

	public static final int CELL = 0;
	public static final int GPS = 1;

	LocationManager locationManager;
	TelephonyManager tm;

	final long UPDATE_INTERVAL = 30 * 1000;

	long mLastLocationMillis = 0;

	Application app;
	
	public LocationMonitor(Application app) {
		super();
		this.app = app;
	}

	private int _method = 0;

	public int getMethod() {
		return _method;
	}

	public GeoPoint getLocation() {
		GeoPoint p = null;
		if (gpsIsFixed()) {
			p = getGpsLoc();
			if (p != null) {
				_method = GPS;
				return p;
			}
		}
		p = getCellLoc();
		if (p != null) {
			_method = CELL;
			return p;
		}
		return null;
	}

	private void init() {
		locationManager = (LocationManager) app
				.getSystemService(Context.LOCATION_SERVICE);
		if (locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
			locationManager.requestLocationUpdates(
					LocationManager.GPS_PROVIDER, UPDATE_INTERVAL, 0,
					locationListener);
			locationManager.addGpsStatusListener(gpsListener);

		} else if (locationManager
				.isProviderEnabled(LocationManager.NETWORK_PROVIDER)) {
			// locationManager.requestLocationUpdates(
			// LocationManager.NETWORK_PROVIDER, UPDATE_INTERVAL,
			// 0, locationListener);
		}
	}

	private GeoPoint getCellLoc() {
		GeoPoint p = null;
		tm = (TelephonyManager) app
				.getSystemService(Context.TELEPHONY_SERVICE);
		GsmCellLocation gcl = (GsmCellLocation) tm.getCellLocation();
		if (gcl != null) {
			int cid = gcl.getCid();
			int lac = gcl.getLac();
			int mcc = Integer.valueOf(tm.getNetworkOperator().substring(0, 3));
			int mnc = Integer.valueOf(tm.getNetworkOperator().substring(3, 5));
			try {
				JSONObject holder = new JSONObject();
				holder.put("version", "1.1.0");
				holder.put("host", "maps.google.com");
				holder.put("request_address", true);
				JSONArray array = new JSONArray();
				JSONObject data = new JSONObject();
				data.put("cell_id", cid);
				data.put("location_area_code", lac);
				data.put("mobile_country_code", mcc);
				data.put("mobile_network_code", mnc);
				array.put(data);
				holder.put("cell_towers", array);
				DefaultHttpClient client = new DefaultHttpClient();
				HttpPost post = new HttpPost("http://www.google.com/loc/json");
				StringEntity se = new StringEntity(holder.toString());
				post.setEntity(se);
				HttpResponse resp = client.execute(post);
				HttpEntity entity = resp.getEntity();
				String result = EntityUtils.toString(entity);
				if (result != null) {
					JSONObject rObject = new JSONObject(result);
					JSONObject location = rObject.getJSONObject("location");
					double lat = location.getDouble("latitude");
					double lng = location.getDouble("longitude");
					p = new GeoPoint((int) (lat * 1E6), (int) (lng * 1E6));
				}
			} catch (Exception e) {

			}
		}
		return p;
	}

	/**
	 * 取得位置信息
	 * 
	 * @return
	 */
	private GeoPoint getGpsLoc() {
		GeoPoint p = null;
		try {
			if(locationManager==null)
				init();
			Criteria criteria = new Criteria();
			criteria.setAccuracy(Criteria.ACCURACY_FINE);
			String bestProvider = locationManager.getBestProvider(criteria,
					false);
			// Log.i(TAG, bestProvider);
			Location location = locationManager
					.getLastKnownLocation(bestProvider);
			if (location != null) {
				double lat = location.getLatitude();
				double lng = location.getLongitude();
				p = new GeoPoint((int) (lat * 1E6), (int) (lng * 1E6));
			}
		} catch (Exception e) {

		}
		return p;
	}

	private boolean gpsIsFixed() {
		return SystemClock.elapsedRealtime() - mLastLocationMillis < 5000;
	}

	private final LocationListener locationListener = new LocationListener() {
		public void onLocationChanged(Location location) {
			if (location == null)
				return;
			mLastLocationMillis = SystemClock.elapsedRealtime();
		}

		@Override
		public void onProviderDisabled(String arg0) {

		}

		@Override
		public void onProviderEnabled(String arg0) {

		}

		@Override
		public void onStatusChanged(String arg0, int arg1, Bundle arg2) {

		}
	};

	GpsStatus.Listener gpsListener = new GpsStatus.Listener() {
		public void onGpsStatusChanged(int event) {
			switch (event) {
			case GpsStatus.GPS_EVENT_FIRST_FIX:

				break;
			case GpsStatus.GPS_EVENT_SATELLITE_STATUS:

				break;
			case GpsStatus.GPS_EVENT_STARTED:

				break;
			case GpsStatus.GPS_EVENT_STOPPED:

				break;
			}
		}
	};
}
